{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Convolutional Neural Network\n",
    "\n",
    "### Convolutional Layers: [128,128,128] ; Dense Layers [128,128,128] \n",
    "### CNN regularized with l1 regularization in dense layers\n",
    "\n",
    "CNN is trained on raw data"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Get the data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Stored variables and their in-db values:\n",
      "X_test              -> defaultdict(<class 'list'>, {0: array([[[-0.000654\n",
      "X_train             -> array([[[-0.00107939, -0.00131855, -0.00122601, ..\n",
      "snrs                -> [-20, -18, -16, -14, -12, -10, -8, -6, -4, -2, 0, \n",
      "y_test              -> defaultdict(<class 'list'>, {0: array([5, 5, 5, ..\n",
      "y_train             -> array([4, 6, 7, ..., 2, 7, 4])\n"
     ]
    }
   ],
   "source": [
    "import warnings\n",
    "warnings.filterwarnings('ignore')\n",
    "\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "import tensorflow as tf\n",
    "from collections import defaultdict\n",
    "from time import time\n",
    "from functools import partial\n",
    "\n",
    "%store -r\n",
    "%store"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Training data:  (80000, 2, 128) and labels:  (80000,)\n",
      "\n",
      "Test data:\n",
      "Total 20 (4000, 2, 128) arrays for SNR values:\n",
      "[-20, -18, -16, -14, -12, -10, -8, -6, -4, -2, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18]\n"
     ]
    }
   ],
   "source": [
    "print(\"Training data: \", X_train.shape, \"and labels: \", y_train.shape)\n",
    "print()\n",
    "print(\"Test data:\")\n",
    "print(\"Total\", len(X_test), X_test[18].shape, \"arrays for SNR values:\")\n",
    "print(sorted(X_test.keys()))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##  Standardize the features"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Training set (80000, 2, 128)\n",
      "Test set corresponding to one snr value (4000, 2, 128)\n"
     ]
    }
   ],
   "source": [
    "from sklearn.preprocessing import StandardScaler\n",
    "\n",
    "sc = StandardScaler()\n",
    "_X_train = np.reshape(X_train, [X_train.shape[0], X_train.shape[1]*X_train.shape[2]])\n",
    "_X_train = sc.fit_transform(_X_train)\n",
    "\n",
    "X_train = np.reshape(_X_train, X_train.shape)\n",
    "print(\"Training set\", X_train.shape)\n",
    "\n",
    "_X_test = defaultdict(list)\n",
    "for snr in snrs:\n",
    "    _X_test[snr] = np.reshape(X_test[snr], [X_test[snr].shape[0], X_test[snr].shape[1]*X_test[snr].shape[2]])\n",
    "    _X_test[snr] = sc.transform(_X_test[snr])\n",
    "    X_test[snr] = np.reshape(_X_test[snr], X_test[snr].shape)\n",
    "    \n",
    "print(\"Test set corresponding to one snr value\", X_test[18].shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Design and train the CNN"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 0 training accuracy : 0.20703125\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_regtech_l1.1\n",
      "Epoch 1 training accuracy : 0.2353515625\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_regtech_l1.1\n",
      "Epoch 2 training accuracy : 0.232421875\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_regtech_l1.1\n",
      "Epoch 3 training accuracy : 0.2626953125\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_regtech_l1.1\n",
      "Epoch 4 training accuracy : 0.251953125\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_regtech_l1.1\n",
      "Epoch 5 training accuracy : 0.29296875\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_regtech_l1.1\n",
      "Epoch 6 training accuracy : 0.30859375\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_regtech_l1.1\n",
      "Epoch 7 training accuracy : 0.283203125\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_regtech_l1.1\n",
      "Epoch 8 training accuracy : 0.31640625\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_regtech_l1.1\n",
      "Epoch 9 training accuracy : 0.322265625\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_regtech_l1.1\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_regtech_l1.1\n",
      "Training took 37.413028 minutes\n"
     ]
    }
   ],
   "source": [
    "height = 2\n",
    "width = 128\n",
    "channels = 1\n",
    "n_features = height * width\n",
    "\n",
    "feature_map1 = 128\n",
    "ksize_conv1 = 2\n",
    "stride_conv1 = 1\n",
    "\n",
    "feature_map2 = 128\n",
    "ksize_conv2 = ksize_conv1\n",
    "stride_conv2 = stride_conv1\n",
    "\n",
    "feature_map3 = 128\n",
    "ksize_conv3 = ksize_conv1\n",
    "stride_conv3 = stride_conv1\n",
    "\n",
    "pool_layer_maps = 128\n",
    "\n",
    "n_fully_conn1 = 128\n",
    "n_fully_conn2 = 128\n",
    "n_fully_conn3 = 128\n",
    "\n",
    "n_classes = 8\n",
    "  \n",
    "X = tf.placeholder(tf.float32, shape=[None, height, width])\n",
    "X_reshaped = tf.reshape(X, shape=[-1, height, width, channels])\n",
    "labels = tf.placeholder(tf.int32, shape=[None])\n",
    "\n",
    "weight_init = tf.contrib.layers.xavier_initializer()\n",
    "activation_func = tf.nn.relu\n",
    "\n",
    "# ------------------ Convolutional and pooling layers ----------------------------\n",
    "\n",
    "def convolutional_layer(X, filter_, ksize, kernel_init, strides, padding):\n",
    "    convolutional_layer = tf.layers.conv2d(X, filters = filter_, kernel_initializer = kernel_init,\n",
    "                                           kernel_size = ksize, strides = strides,\n",
    "                                          padding = padding, activation = activation_func)\n",
    "    return convolutional_layer\n",
    "\n",
    "def pool_layer(convlayer, ksize, strides, padding, pool_maps):\n",
    "    pool = tf.nn.max_pool(convlayer, ksize, strides, padding)\n",
    "    dim1, dim2 = int(pool.get_shape()[1]), int(pool.get_shape()[2])\n",
    "    pool_flat = tf.reshape(pool, shape = [-1, pool_maps * dim1 * dim2])\n",
    "    return pool_flat\n",
    "\n",
    "conv_layer1 = convolutional_layer(X_reshaped, feature_map1, ksize_conv1, weight_init, stride_conv1, padding = \"SAME\")\n",
    "\n",
    "conv_layer2 = convolutional_layer(conv_layer1, feature_map2, ksize_conv2, weight_init, stride_conv2, padding = \"SAME\")\n",
    "\n",
    "conv_layer3 = convolutional_layer(conv_layer2, feature_map3, ksize_conv3, weight_init, stride_conv3, padding = \"SAME\")\n",
    "\n",
    "pool_layer_flat = pool_layer(conv_layer3, [1,2,2,1], [1,2,2,1], \"VALID\", pool_layer_maps)\n",
    "\n",
    "# ----------------- Fully connected layers -------------------\n",
    "\n",
    "scale_val = 0.001\n",
    "new_dense_layer = partial(tf.layers.dense, kernel_initializer = weight_init,\n",
    "                          kernel_regularizer = tf.contrib.layers.l1_regularizer(scale_val), \n",
    "                          activation = activation_func)\n",
    "\n",
    "dense_layer1 = new_dense_layer(pool_layer_flat, n_fully_conn1)\n",
    "\n",
    "dense_layer2 = new_dense_layer(dense_layer1, n_fully_conn2)\n",
    "\n",
    "dense_layer3 = new_dense_layer(dense_layer2, n_fully_conn3)\n",
    "\n",
    "# ----------------- Output softmax layer ---------------------------\n",
    "\n",
    "logits = tf.layers.dense(dense_layer3, n_classes)\n",
    "softmax_activations = tf.nn.softmax(logits)\n",
    "\n",
    "# ----------------- Specify performance measure -------------------------------\n",
    "\n",
    "cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits = logits, labels = labels)\n",
    "\n",
    "loss = tf.reduce_mean(cross_entropy)\n",
    "regularization_loss = tf.get_collection(tf.GraphKeys.REGULARIZATION_LOSSES)\n",
    "total_loss = tf.add_n([loss] + regularization_loss)\n",
    "\n",
    "optimizer = tf.train.AdamOptimizer()\n",
    "train_operation = optimizer.minimize(total_loss)\n",
    "\n",
    "correct_predictions = tf.nn.in_top_k(logits, labels, 1)\n",
    "accuracy = tf.reduce_mean(tf.cast(correct_predictions, tf.float32))\n",
    "\n",
    "# ---------------- Execution phase -------------------------------------------\n",
    "    \n",
    "n_epochs = 10\n",
    "batch_size = 1024\n",
    "n_train = X_train.shape[0]\n",
    "n_iter = n_train//batch_size\n",
    "\n",
    "acc_test = defaultdict(list)\n",
    "\n",
    "path = \"./CNN_regtech_l1.1\"  \n",
    "saver = tf.train.Saver()\n",
    "\n",
    "start = time()\n",
    "\n",
    "with tf.Session() as sess:\n",
    "    tf.global_variables_initializer().run()\n",
    "    for epoch in range(n_epochs):\n",
    "        for iteration in range(n_iter):\n",
    "            rand_indices = np.random.choice(n_train,batch_size)    \n",
    "            X_batch, y_batch = X_train[rand_indices], y_train[rand_indices]\n",
    "            sess.run(train_operation, feed_dict={X: X_batch, labels: y_batch})\n",
    "        acc_train = accuracy.eval(feed_dict={X: X_batch, labels: y_batch})\n",
    "        print(\"Epoch {} training accuracy : {}\".format(epoch, acc_train))\n",
    "        save_path = saver.save(sess, path)\n",
    "        saver.restore(sess, path)\n",
    "    saver.restore(sess, path)\n",
    "    for snr in snrs:\n",
    "        acc_test[snr] = accuracy.eval(feed_dict={X: X_test[snr], labels: y_test[snr]})\n",
    "\n",
    "print(\"Training took %f minutes\"%(float(time() - start)/60.0))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##  Test the classifier"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "CNN's test accuracy on -20dB SNR samples = 0.11599999666213989\n",
      "CNN's test accuracy on -18dB SNR samples = 0.1197500005364418\n",
      "CNN's test accuracy on -16dB SNR samples = 0.12925000488758087\n",
      "CNN's test accuracy on -14dB SNR samples = 0.13574999570846558\n",
      "CNN's test accuracy on -12dB SNR samples = 0.16574999690055847\n",
      "CNN's test accuracy on -10dB SNR samples = 0.2160000056028366\n",
      "CNN's test accuracy on -8dB SNR samples = 0.2757500112056732\n",
      "CNN's test accuracy on -6dB SNR samples = 0.3160000145435333\n",
      "CNN's test accuracy on -4dB SNR samples = 0.2952499985694885\n",
      "CNN's test accuracy on -2dB SNR samples = 0.3232499957084656\n",
      "CNN's test accuracy on 0dB SNR samples = 0.359250009059906\n",
      "CNN's test accuracy on 2dB SNR samples = 0.41624999046325684\n",
      "CNN's test accuracy on 4dB SNR samples = 0.4325000047683716\n",
      "CNN's test accuracy on 6dB SNR samples = 0.43650001287460327\n",
      "CNN's test accuracy on 8dB SNR samples = 0.4165000021457672\n",
      "CNN's test accuracy on 10dB SNR samples = 0.42925000190734863\n",
      "CNN's test accuracy on 12dB SNR samples = 0.4232499897480011\n",
      "CNN's test accuracy on 14dB SNR samples = 0.42500001192092896\n",
      "CNN's test accuracy on 16dB SNR samples = 0.41624999046325684\n",
      "CNN's test accuracy on 18dB SNR samples = 0.4307500123977661\n"
     ]
    }
   ],
   "source": [
    "for snr in snrs:\n",
    "    print(\"CNN's test accuracy on {}dB SNR samples = {}\".format(snr,acc_test[snr]))  "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##  Visualize classifier's performance on test set"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\nFPHbAAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f5b71e98550>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.style.use('classic')\n",
    "%matplotlib inline\n",
    "\n",
    "acc_test = sorted(acc_test.items())\n",
    "new_acc = []\n",
    "for i in range(len(acc_test)):\n",
    "    new_acc.append(acc_test[i][1])\n",
    "acc_test_values = new_acc \n",
    "\n",
    "fig1 = plt.figure(figsize=(10, 6), dpi=100)\n",
    "x = snrs\n",
    "y = list(acc_test_values)\n",
    "plt.plot(x, y, marker=\"o\", linewidth=2.0, linestyle='dashed', color='royalblue')\n",
    "plt.axis([-20, 20, 0, 1])\n",
    "plt.xticks(np.arange(min(x), max(x)+1, 2.0))\n",
    "plt.yticks(np.arange(0, 1, 0.10))\n",
    "\n",
    "ttl = plt.title('SNR vs Accuracy', fontsize=16)\n",
    "ttl.set_weight('bold')\n",
    "plt.xlabel('SNR (dB)', fontsize=14)\n",
    "plt.ylabel('Test accuracy', fontsize=14)\n",
    "plt.grid()\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Restoring parameters from ./CNN_regtech_l1.1\n",
      "Confusion Matrix\n",
      "       8PSK  BPSK  CPFSK  GFSK  PAM4  QAM16  QAM64  QPSK\n",
      "8PSK    NaN   NaN    NaN   NaN   NaN    NaN    NaN   NaN\n",
      "BPSK   0.01  0.66   0.00  0.03  0.26   0.01   0.01  0.03\n",
      "CPFSK  0.17  0.00   0.46  0.12  0.00   0.10   0.12  0.03\n",
      "GFSK   0.18  0.00   0.04  0.36  0.00   0.19   0.16  0.08\n",
      "PAM4   0.00  0.41   0.00  0.01  0.57   0.01   0.00  0.00\n",
      "QAM16  0.00  0.00   0.00  0.40  0.00   0.00   0.20  0.40\n",
      "QAM64  0.22  0.00   0.08  0.18  0.00   0.22   0.22  0.08\n",
      "QPSK   0.05  0.00   0.00  0.10  0.00   0.14   0.11  0.60\n"
     ]
    },
    {
     "data": {
      "image/png": "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\nvKyyOERkbvJtZM5qZ0RUOlmr1ZWbtQeAKyIXm2kKJa1oJNn6H86RG8o95IIi2yPi4uoiPKKVYu1J\nfdk5IogAAASzSURBVA51eew86hbl1K1+LDJ15IxmalWR3XDryDE1IuJlAEmzya67Na6oT1xErFYu\niLNGuZlIVNnSg17TipaRY8B3kbOVKel6Ve5Q1jKxvovDw0mlte+KukW5ZW0NVzf+O40cT9tPjv9+\nocqu+v5IubRo1RP0gMMV4JyImCtpAHkDcVDSueQGI+vIrtsLI+KgYzU7wi1ra7iI2COpg2yhXEnu\n/XtNRPyp2sj6n2apqIvdQLukKZE59Uhqi4jXJW0m06G2Nknl10qx2inALWsza4iSKrSAXFDm0ZIK\nVXtuLbk942MRsarqsdVWitVODc6zNrOGKGPmy4C95C5gcyVNkPQEueLeHuDPpWyllV8rxWqnBres\nzayhWimtqJVitf7NlbWZVaKV0opaKVbrn9wNbmZVaaW0olaK1foht6zNzMyanFvWZmZmTc6VtZmZ\nWZNzZW1mZtbkXFmbmZk1OVfWZl1I+p+kzZJ2SHpc0qATONflklaW72dKWtBL2dMl3XEc11hU9gnv\na/lK9zQ3s2Pnytqsu70R0R4RE8iUna91LVCWo+yrAIiIlRHxnV7KjQDuPKZIj49TQMxajCtrs949\nD3xU0ocl7ZT0qKQdwLmSpkt6QdKm0gIfAiDpKkl/lLQJuK52IklfkbS0fH+WpOWStkraImkKsBgY\nW1r195dy35S0sZRbVHeub0l6RdJzwPlHC7yHawCoPN8m6ekS/zZJ15TjQyT9prxmu6RZ5fgSSX8o\n5+vtpsPMTjLvumXWXa0yOw34NLC6HB8H3BwRL0kaCSwEpkVEZ+nenl92E3sY+GRE7JL0eJdz11q1\nDwLPRsR1pZU+FLgH+FhEtJfrTwfGRcTkUmaFpMuAfcAXgYvIdao3A5uO8j6Odo36GPYD10bE2+X9\nbABWAFcBeyLi6hLHMEkjStnx5djwY/mBmtmJcWVt1t3gsg0iZMv6h8A5wF8i4qVyfApwIfD7UhEO\nANYD44FdEbGrlPsZcPtRrjEVuBkObxrxVlmHut4MYHqJRUAbecMwHHgiIt4B3pG0oof30e0aXZ4X\nsFjSJ4BDwGhJZwE7gA5Ji4GnImKdpPcDnZIeAVaRezqbWYO4sjbrbl+tdVtThqj31h8C1kbEjV3K\nTezjNfoybixgcUQ80uUad/Xx9e9W5kbgTOCSiDgk6TVgUES8KmkS8BngXklPR8S9kiYD04BZwLzy\nvZk1gMeszbrrafJY/fENwKWSxgJIGixpHLAT+Iik80q5OT2c6xnKZDJJ75M0jGz5Dqsr81tgrqS2\nUm60pA8CzwGflzSwvG5mH69R6wavvY/TgTdKRX0F8KFSdhTQGRGPAR1AexmPPyMi1gDzyS54M2sQ\nt6zNuuupRXr4eET8U9ItwC8kDSzPLSyt0q8CqyTtJbvRhx7lXF8HHpZ0K3AQuCMiXiwT1rYDqyPi\nbkkXAOtLy/4t4KaI2CLpV8B24B/Axh7i7XYN4MW69/FzYKWkbeSY985yfALZDX4I+G953XDgybo0\ntm/0cE0zew94Iw8zM7Mm525wMzOzJufK2szMrMm5sjYzM2tyrqzNzMyanCtrMzOzJufK2szMrMm5\nsjYzM2tyrqzNzMya3P8BFUjAVE1Ux9YAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f5b71ec62e8>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Confusion Matrix\n",
    "\n",
    "with tf.Session() as sess:\n",
    "    saver.restore(sess, path)\n",
    "    Z = logits.eval(feed_dict = {X : X_test[18]})\n",
    "    predicted_18dB = np.argmax(Z, axis = 1)\n",
    "    \n",
    "from sklearn.metrics import confusion_matrix\n",
    "%matplotlib inline\n",
    "\n",
    "classes = ['8PSK', 'BPSK', 'CPFSK', 'GFSK', 'PAM4', 'QAM16', 'QAM64', 'QPSK']\n",
    "conf_matrix = confusion_matrix(predicted_18dB, y_test[18])  \n",
    "\n",
    "conf_matrix = conf_matrix.astype('float') / conf_matrix.sum(axis=1)[:, np.newaxis]\n",
    "conf_matrix = conf_matrix.round(decimals = 2)\n",
    "\n",
    "import pandas as pd\n",
    "\n",
    "df = pd.DataFrame(data = conf_matrix, columns = classes, index = classes) \n",
    "print(\"Confusion Matrix\")\n",
    "print(df)\n",
    "\n",
    "fig1 = plt.figure(figsize=(10, 6), dpi=100)\n",
    "plt.imshow(conf_matrix, interpolation = 'nearest', cmap = plt.cm.Purples)\n",
    "ticks = np.arange(len(classes))\n",
    "plt.title(\"Confusion Matrix\")\n",
    "plt.xticks(ticks, classes, rotation=45)\n",
    "plt.yticks(ticks, classes)\n",
    "\n",
    "plt.ylabel('True class')\n",
    "plt.xlabel('Predicted class')\n",
    "\n",
    "plt.tight_layout()\n",
    "plt.colorbar()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
